#pragma once
#include "mytypes.h"
#include "Collision.h"

namespace poly
{
	struct RigidBody
	{
		RigidBody(void);
		// linear properties
		float3 pos;
		float3 vel;
		float3 acc;

		// rotational properties
		float33 orientation;
		float3 rotVel;

		float3 rotMomentum;

		// inertial properties
		float invMass;
		float33 invLocalInertia;
		float33 invInertia() const;

		// collision response properties
		float elasticity;
		float friction;

		// methods
		void addForce( float3 const & force );
		void addForce( float3 const & force, float3 const & position );
		void addTorque( float3 const & torque );
		void addLinearImpulse( float3 const & force );
		void addLinearImpulse( float3 const & force, float3 const &position );
		void addRotationalImpulse( float3 const &torque );

		void addForceLocal( float3 const & force );
		void addForceLocal( float3 const & force, float3 const & position );
		void addTorqueLocal( float3 const & torque );
		void addLinearImpulseLocal( float3 const & force );
		void addLinearImpulseLocal( float3 const & force, float3 const &position );
		void addRotationalImpulseLocal( float3 const &torque );

		void displace( float3 const & distance );
		void rotate( float3 const & rotation );

		// applies impulses on rigid bodies to clear out of a collision
		void resolveCollision( RigidBody &RB,
			Contact const & contact );

		// applies impulses on rigid bodies to keep bodies attached at a joint
		void resolveJoint( RigidBody &RB,
			float3 const & jointPosition );

		// applies impulses on rigid bodies to keep then sliding at the slide point in the given direction
		void resolveSlide( RigidBody &RB,
			float3 const & slidePt, float3 const & slideDir );

		void step( float dt );
		void resetForces();

		float44 world() const;

	private:
		float3 force;
		float3 torque;
	};

} // end of poly
